package com.netcracker.util.service;

import com.netcracker.db.exception.DBException;
import com.netcracker.entity.Genre;
import com.netcracker.entity.record.GenreRecord;
import com.netcracker.util.dao.DAOFacade;
import com.netcracker.util.service.exception.DataTransmittingException;
import com.netcracker.util.service.exception.NullDataException;
import com.netcracker.util.service.exception.WrongGenreException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenreService {
        
    private DAOFacade daoFacade;
    
    public GenreService(DAOFacade daoFacade) {
        this.daoFacade = daoFacade;
    }
    
    public void setDAOFacade(DAOFacade daoFacade) {
        this.daoFacade = daoFacade;
    }
    
    public void updateGenre(GenreRecord genre) throws WrongGenreException, DataTransmittingException {
        try {
            checkRecord(genre);
            daoFacade.getGenreDAO().edit(genre);
        } catch (DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }
    
    public void deleteGenre(int genreID) throws DataTransmittingException {
        try {
            daoFacade.getGenreDAO().remove(genreID);
        } catch(DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }
    
    public void addGenre(GenreRecord genre) throws WrongGenreException, DataTransmittingException {
        try {
            checkRecord(genre);
            daoFacade.getGenreDAO().create(genre);
        } catch (DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }
    
    public List<Genre> getAllGenres() throws DataTransmittingException, NullDataException {
        try {
            List<Genre> genres = daoFacade.getGenreDAO().findAll();
            if (genres == null) 
                throw new NullDataException("There are no genres.");
            return genres;


        } catch(DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }
    
    public Genre readGenre(int genreID) throws DataTransmittingException, NullDataException {
        try {
            Genre genre = daoFacade.getGenreDAO().find(genreID);
            if (genre == null) 
                throw new NullDataException("Genre with this id doesn't exist");
            return genre;
        } catch(DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }
 
    private void checkRecord(GenreRecord genre) throws WrongGenreException {
        if (genre.getName() == null || genre.getName().equals("")) 
            throw new WrongGenreException("Not all fields of genre are filled!");
    }
    
    public List<Genre> getGenreTree() throws NullDataException, DataTransmittingException {
        try {
            List<Genre> genres = daoFacade.getGenreDAO().findAll();
            if (genres == null) 
                throw new NullDataException("GenreTree doesn't exist");
            return doGenreTree(genres);
        } catch(DBException ex) {
            throw new DataTransmittingException(ex.getMessage(), ex);
        }
    }

    private List<Genre> doGenreTree(List<Genre> genres)
    {
        Map lookup = new HashMap<Integer, Genre>();
        List<Genre> nested = new ArrayList<Genre>();
        for (Genre genre:genres)
        {
            lookup.put(genre.getId(), genre);
        }
        for(Genre item : genres)
        {
            if (item.getParentID() != null)
            {
                Genre genre = (Genre)lookup.get(item.getParentID());
                genre.addSubGenre(item);
            }
            else
            {
                nested.add(item);
            }
            
        }
        return nested;
    }
    
}
